/**
 * This file is part of Adaptools.
 * 
 * Adaptools is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 * 
 * Adaptools is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 * along with Adaptools.  If not, see http://www.gnu.org/licenses/. 
 */
package org.adaptools.repository.base;

import java.io.Serializable;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;

import org.adaptools.base.BasicRule;
import org.adaptools.base.Rule;
import org.adaptools.repository.util.UniqueIdentifier;
import org.apache.log4j.Logger;

/**
 * This is an extencion of {@link BasicRule}
 * 
 * This class has great importance to the system. It is responsible to create
 * and transport all system rules during all the time of live..
 * 
 * @author Denys G. Santos (gsdenys@gmail.com)
 * @since 3.0.0
 */
public class RuleBasicRepository extends BasicRule implements Rule, Serializable {
	private final static Logger LOG = Logger.getLogger(RuleBasicRepository.class);
	
	private static final long serialVersionUID = -5895253298419715794L;

	/**
	 * Default Builder
	 */
	public RuleBasicRepository() {
		super();

		LOG.debug("Create new empty Rule");

		// set uuid to the Rule
		String uuid = UniqueIdentifier.generateUUID();
		this.setId(uuid);
	}

	/**
	 * @see java.lang.Object#equals(java.lang.Object)
	 */
	@Override
	public boolean equals(Object obj) {
		if (this == obj) {
			return true;
		}
		if (obj == null) {
			return false;
		}
		if (!(obj instanceof RuleBasicRepository)) {
			return false;
		}

		RuleBasicRepository other = (RuleBasicRepository) obj;

		String[] compareMethods = { "getAdaptive", "getInput", "getOutput",
				"getPush", "getSource", "getTarget" };

		Class<? extends RuleBasicRepository> cls = null;
		Method meth = null;
		String local = null;
		String compare = null;

		try {
			cls = this.getClass();

			for (String string : compareMethods) {
				meth = cls.getMethod(string);
				local = (String) meth.invoke(this);
				compare = (String) meth.invoke(other);

				if (local == null) {
					if (compare != null) {
						return false;
					}
				} else if (!compare.startsWith("?")) {
					if (!local.equals(compare)) {
						return false;
					}
				}
			}

		} catch (NoSuchMethodException e) {
			LOG.error("*****************************************************************************************");
			LOG.error("*** Oh No....  That should not happen... Please, check your compilation and try again ***");
			LOG.error("*****************************************************************************************");
			e.printStackTrace();
		} catch (SecurityException e) {
			LOG.error("*****************************************************************************************");
			LOG.error("*** Oh No....  That should not happen... Please, check your compilation and try again ***");
			LOG.error("*****************************************************************************************");
			e.printStackTrace();
		} catch (IllegalAccessException e) {
			LOG.error("*****************************************************************************************");
			LOG.error("*** Oh No....  That should not happen... Please, check your compilation and try again ***");
			LOG.error("*****************************************************************************************");
			e.printStackTrace();
		} catch (IllegalArgumentException e) {
			LOG.error("*****************************************************************************************");
			LOG.error("*** Oh No....  That should not happen... Please, check your compilation and try again ***");
			LOG.error("*****************************************************************************************");
			e.printStackTrace();
		} catch (InvocationTargetException e) {
			LOG.error("*****************************************************************************************");
			LOG.error("*** Oh No....  That should not happen... Please, check your compilation and try again ***");
			LOG.error("*****************************************************************************************");
			e.printStackTrace();
		}

		return true;
	}
	
	/**
	 * @see org.adaptools.base.Copyable#copy()
	 */
	@Override
	public Rule copy() {
		Rule rule = new RuleBasicRepository();

		rule.setHeader(super.getHeader());
		rule.setInput(super.getInput());
		rule.setSource(super.getSource());
		rule.setTarget(super.getTarget());
		rule.setOutput(super.getOutput());
		rule.setPush(super.getPush());
		rule.setAdaptive(super.getAdaptive());

		return rule;
	}
}